package com.example.chat.websocket;

import cn.hutool.json.JSONUtil;
import com.example.chat.domain.entity.ChatContent;
import com.example.chat.domain.entity.Receive_message;
import com.example.chat.service.ChatService;
import com.example.chat.service.GroupMessageService;
import com.example.chat.utils.RedisConstants;
import jakarta.annotation.Resource;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * WebSocket服务
 */
@Component
@Slf4j
@ServerEndpoint("/ws/{id}")
public class WebSocketServer {

    //存放会话对象
//    private static Map<String, Session> sessionMap = new HashMap();
    private final static ConcurrentHashMap<Long,Session> sessionMap = new ConcurrentHashMap<>();
    private static StringRedisTemplate stringRedisTemplate;
    private static GroupMessageService groupMessageService;
    private static ChatService chatService;
    private Session session;
    private Long currentUserId;
    @Resource
    public void setGroupMessageService(GroupMessageService groupMessageService){
        WebSocketServer.groupMessageService = groupMessageService;
    }
    @Resource
    public void setChatService(ChatService chatService){
        WebSocketServer.chatService = chatService;
    }
    @Resource
    public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate){
        WebSocketServer.stringRedisTemplate = stringRedisTemplate;
    }
    public void setSessionAndID(Session session,Long id){
        this.session = session;
        this.currentUserId = id;
    }
    @OnOpen
    public void onOpen(Session session, @PathParam("id") Long id) {
        log.info("客户端：{}建立连接",id);
        setSessionAndID(session,id);
        sessionMap.put(id,session);
        log.info("当前用户连接数：{}",sessionMap.size());
    }

    @OnMessage
    public void onMessage(String message) {
        log.info("收到来自客户端,ID为{}的信息:{}",currentUserId,message);
        Receive_message socket_message = JSONUtil.toBean(message, Receive_message.class);
        String msg = socket_message.getMessage();
        Integer type = socket_message.getType();
        Long receiver = socket_message.getReceiver();
        //添加记录进数据库
        if(Integer.valueOf(1).equals(type)){
            Long msgId = chatService.saveMessage(msg,currentUserId,receiver);
            sendToOne(msg,receiver,msgId);
        }else if(Integer.valueOf(2).equals(type)){
            Long msgId = groupMessageService.saveGroupMessage(msg, currentUserId, receiver);
            sendToGroupClient(msg,receiver,msgId);
        }else{
            log.info("类型为{}的消息{}",socket_message.getType(),socket_message.getMessage());
        }
    }

    @OnClose
    public void onClose() {
        if (sessionMap.containsKey(currentUserId)) {
            log.info("ID：{}连接断开:",this.currentUserId);
            sessionMap.remove(this.currentUserId);
            log.info("当前用户连接数：{}",sessionMap.size());
        }
    }
    @OnError
    public void onError(Session session, Throwable t) {
        log.info("【websocket消息】出现未知错误 ");
//        t.printStackTrace();
    }

//    { id: 2, type: 2, text: 'hello,我是momTrue', time: '17:04' },
    public void sendToOne(String message,Long receiver,Long msgId) {
        if (sessionMap.containsKey(receiver)) {
            Session session = sessionMap.get(receiver);
            if (session.isOpen()) {
                try {
                    String forwardMessageJson = chatService.forWard(msgId, message,currentUserId,receiver);
                    session.getBasicRemote().sendText(forwardMessageJson);
                    log.info("发送成功");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }else {
            log.info("用户不在线");
        }
    }

    public void sendToGroupClient(String message,Long receiver,Long msgId) {
        log.info("消息：{}",message);
        log.info("转发群聊，{}",receiver);
        Set<String> stringSet = stringRedisTemplate.opsForZSet()
                .range(RedisConstants.CHAT_GROUP_USERS_ID+receiver, 0, -1);
        List<Long> ids = stringSet.stream().map(Long::valueOf).collect(Collectors.toList());
        log.info("当前群聊的用户："+ids);
        ChatContent chatContent = groupMessageService
                .forWard(msgId, message, currentUserId, receiver);
        for (Long id : ids) {
            if (sessionMap.containsKey(id)) {
                Session session = sessionMap.get(id);
                if (session.isOpen()) {
                    try {
                        chatContent.setType(id.equals( currentUserId) ? 2 : 1);
                        session.getAsyncRemote().sendText(JSONUtil.toJsonStr(chatContent));
                        log.info("发送成功");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }else {
                log.info("id为{}的用户不在线，",id);
            }
        }
    }

}
